#include "gtest/gtest.h"
#include "../BaseUtil/MyTest.h"
#include "DOMCoreImp.h"
namespace DOMCoreImp {

class NodeIteratorImpTest : public testing::Test {
protected:
	class DummyFilter : public NodeFilter {
	public:
		DummyFilter( Node * target, short behavior )
		: target_(target), behavior_(behavior)
		{}

		virtual short acceptNode(Node * n) {
			if( n == target_ ) return behavior_;
			return NodeFilter::FILTER_ACCEPT;
		}

	private:
		Node * target_;
		short behavior_;
	};

    virtual void SetUp() {
		doc = new DocumentImp();

		elem1 = doc->createElement("Elem1");
		elem11 = doc->createElement("Elem11");
		elem12 = doc->createElement("Elem12");
		elem121 = doc->createElement("Elem121");
		elem122 = doc->createElement("Elem122");
		elem1221 = doc->createElement("Elem1221");
		elem1222 = doc->createElement("elem1222");
		elem13 = doc->createElement("Elem13");

		doc->appendChild( elem1 );
		elem1->appendChild( elem11 );
		elem1->appendChild( elem12 );
		elem12->appendChild( elem121 );
		elem12->appendChild( elem122 );
		elem122->appendChild( elem1221 );
		elem122->appendChild( elem1222 );
		elem1->appendChild( elem13 );

		skipElem122 = new DummyFilter( elem122, NodeFilter::FILTER_SKIP );
		rejectElem122 = new DummyFilter( elem122, NodeFilter::FILTER_REJECT );
    }

    virtual void TearDown() {
		delete rejectElem122;
		delete skipElem122;
		delete doc;
    }

	DocumentImp * doc;
	Element * elem1, * elem11, * elem12, * elem121, * elem122, * elem1221, * elem1222, * elem13;
	NodeFilter * skipElem122, * rejectElem122;
};

TEST_F(NodeIteratorImpTest, Inheritance) {
	NodeIteratorPtr(new NodeIteratorImp(NULL, 0, NULL, false));
}

TEST_F(NodeIteratorImpTest, CreateNodeIterator) {
	NodeIterator * iter = doc->createNodeIterator( elem1, NodeFilter::SHOW_ALL, NULL, false );
	ASSERT_TRUE( iter );

	ASSERT_EQ( elem1, iter->getRoot() );
	ASSERT_EQ( NodeFilter::SHOW_ALL, iter->getWhatToShow() );
	ASSERT_EQ( NULL, iter->getFilter() );
	ASSERT_EQ( false, iter->getExpandEntityReferences() );
}

TEST_F(NodeIteratorImpTest, NodeIteratorNextNode) {
	NodeIterator * iter = doc->createNodeIterator( elem1, NodeFilter::SHOW_ALL, NULL, false );

	ASSERT_EQ( elem1, iter->nextNode() ); // I'm not sure whether it starts from Root or next one.
	ASSERT_EQ( elem11, iter->nextNode() );
	ASSERT_EQ( elem12, iter->nextNode() );
	ASSERT_EQ( elem121, iter->nextNode() );
	ASSERT_EQ( elem122, iter->nextNode() );
	ASSERT_EQ( elem1221, iter->nextNode() );
	ASSERT_EQ( elem1222, iter->nextNode() );
	ASSERT_EQ( elem13, iter->nextNode() );
	ASSERT_EQ( NULL, iter->nextNode() );
	ASSERT_EQ( NULL, iter->nextNode() );
	ASSERT_EQ( elem13, iter->previousNode() );

	iter->detach();
}

TEST_F(NodeIteratorImpTest, NodeIteratorPreviouseNode) {
	NodeIterator * iter = doc->createNodeIterator( elem1, NodeFilter::SHOW_ALL, NULL, false );

	ASSERT_EQ( elem1, iter->nextNode() );
	ASSERT_EQ( elem11, iter->nextNode() );
	ASSERT_EQ( elem12, iter->nextNode() );
	ASSERT_EQ( elem121, iter->nextNode() );
	ASSERT_EQ( elem122, iter->nextNode() );
	ASSERT_EQ( elem1221, iter->nextNode() );
	ASSERT_EQ( elem1222, iter->nextNode() );
	ASSERT_EQ( elem13, iter->nextNode() );
	ASSERT_EQ( NULL, iter->nextNode() );

	ASSERT_EQ( elem13, iter->previousNode() );
	ASSERT_EQ( elem1222, iter->previousNode() );
	ASSERT_EQ( elem1221, iter->previousNode() );
	ASSERT_EQ( elem122, iter->previousNode() );
	ASSERT_EQ( elem121, iter->previousNode() );
	ASSERT_EQ( elem12, iter->previousNode() );
	ASSERT_EQ( elem11, iter->previousNode() );
	ASSERT_EQ( elem1, iter->previousNode() );
	ASSERT_EQ( NULL, iter->previousNode() );
	ASSERT_EQ( elem1, iter->nextNode() );

	iter->detach();
}

TEST_F(NodeIteratorImpTest, NextNodeWithWhatToShow) {
	NodeIterator * iter = doc->createNodeIterator( elem1, NodeFilter::SHOW_ATTRIBUTE, skipElem122, false );
	ASSERT_TRUE( iter );
	ASSERT_EQ( NULL, iter->nextNode() );

	iter->detach();
}

TEST_F(NodeIteratorImpTest, NextNodeWithSkipFilter) {
	NodeIterator * iter = doc->createNodeIterator( elem1, NodeFilter::SHOW_ALL, skipElem122, false );
	ASSERT_EQ( skipElem122, iter->getFilter() );

	ASSERT_EQ( elem1, iter->nextNode() ); // I'm not sure whether it starts from Root or next one.
	ASSERT_EQ( elem11, iter->nextNode() );
	ASSERT_EQ( elem12, iter->nextNode() );
	ASSERT_EQ( elem121, iter->nextNode() );
	ASSERT_EQ( elem1221, iter->nextNode() );
	ASSERT_EQ( elem1222, iter->nextNode() );
	ASSERT_EQ( elem13, iter->nextNode() );
	ASSERT_EQ( NULL, iter->nextNode() );

	iter->detach();
}

TEST_F(NodeIteratorImpTest, NextNodeWithRejectFilter) {
	NodeIterator * iter = doc->createNodeIterator( elem1, NodeFilter::SHOW_ALL, rejectElem122, false );
	ASSERT_EQ( rejectElem122, iter->getFilter() );

	ASSERT_EQ( elem1, iter->nextNode() );
	ASSERT_EQ( elem11, iter->nextNode() );
	ASSERT_EQ( elem12, iter->nextNode() );
	ASSERT_EQ( elem121, iter->nextNode() );
	ASSERT_EQ( elem1221, iter->nextNode() );
	ASSERT_EQ( elem1222, iter->nextNode() );
	ASSERT_EQ( elem13, iter->nextNode() );
	ASSERT_EQ( NULL, iter->nextNode() );

	iter->detach();
}

TEST_F(NodeIteratorImpTest, PreviousNodeWithSkipFilter) {
	NodeIterator * iter = doc->createNodeIterator( elem1, NodeFilter::SHOW_ALL, skipElem122, false );
	ASSERT_EQ( skipElem122, iter->getFilter() );

	ASSERT_EQ( elem1, iter->nextNode() );
	ASSERT_EQ( elem11, iter->nextNode() );
	ASSERT_EQ( elem12, iter->nextNode() );
	ASSERT_EQ( elem121, iter->nextNode() );
	ASSERT_EQ( elem1221, iter->nextNode() );
	ASSERT_EQ( elem1222, iter->nextNode() );
	ASSERT_EQ( elem13, iter->nextNode() );
	ASSERT_EQ( NULL, iter->nextNode() );

	ASSERT_EQ( elem13, iter->previousNode() );
	ASSERT_EQ( elem1222, iter->previousNode() );
	ASSERT_EQ( elem1221, iter->previousNode() );
	ASSERT_EQ( elem121, iter->previousNode() );
	ASSERT_EQ( elem12, iter->previousNode() );
	ASSERT_EQ( elem11, iter->previousNode() );
	ASSERT_EQ( elem1, iter->previousNode() );
	ASSERT_EQ( NULL, iter->previousNode() );

	iter->detach();
}

TEST_F(NodeIteratorImpTest, PreviousNodeWithRejectFilter) {
	NodeIterator * iter = doc->createNodeIterator( elem1, NodeFilter::SHOW_ALL, rejectElem122, false );
	ASSERT_EQ( rejectElem122, iter->getFilter() );

	ASSERT_EQ( elem1, iter->nextNode() );
	ASSERT_EQ( elem11, iter->nextNode() );
	ASSERT_EQ( elem12, iter->nextNode() );
	ASSERT_EQ( elem121, iter->nextNode() );
	ASSERT_EQ( elem1221, iter->nextNode() );
	ASSERT_EQ( elem1222, iter->nextNode() );
	ASSERT_EQ( elem13, iter->nextNode() );
	ASSERT_EQ( NULL, iter->nextNode() );

	ASSERT_EQ( elem13, iter->previousNode() );
	ASSERT_EQ( elem1222, iter->previousNode() );
	ASSERT_EQ( elem1221, iter->previousNode() );
	ASSERT_EQ( elem121, iter->previousNode() );
	ASSERT_EQ( elem12, iter->previousNode() );
	ASSERT_EQ( elem11, iter->previousNode() );
	ASSERT_EQ( elem1, iter->previousNode() );
	ASSERT_EQ( NULL, iter->previousNode() );

	iter->detach();
}

}


